package cn.itcast.bos.service.action.teke_delivary.impl;

import java.util.Date;
import java.util.UUID;

import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.Session;
import javax.ws.rs.core.MediaType;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.cxf.jaxrs.client.WebClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.filter.DelegatingFilterProxy;

import cn.itcast.bos.domain.base.Area;
import cn.itcast.bos.domain.base.Courier;
import cn.itcast.bos.domain.base.FixedArea;
import cn.itcast.bos.domain.base.SubArea;
import cn.itcast.bos.domain.contant.Constants;
import cn.itcast.bos.domain.take_delivary.Order;
import cn.itcast.bos.domain.take_delivary.WorkBill;
import cn.itcast.bos.service.action.teke_delivary.OrderService;
import cn.itcast.bos.web.Dao.base.AreaRepository;
import cn.itcast.bos.web.Dao.base.fixedAreaRepository;
import cn.itcast.bos.web.Dao.teke_delivary.OrderRepository;
import cn.itcast.bos.web.Dao.teke_delivary.WorkBillRepository;

@Service
@Transactional
public class OrderServiceimpl implements OrderService {

	// 注入fixedAreaRepository
	@Autowired
	private fixedAreaRepository fixedarearepository;
	// 注入OrderRepository
	@Autowired
	private OrderRepository orderRepository;
	// 注入AreaRepository
	@Autowired
	private AreaRepository areaRepository;
	// 注入WorkBillRepository
	@Autowired
	private WorkBillRepository workBillRepository;
	// 注入短信发送模板
	@Autowired
	@Qualifier("jmsQueueTemplate") // 指定发送模式
	private JmsTemplate jmsTemplate;

	@Override
	public void saveOrder(Order order) {
		System.out.println(order); // 输出的是什么？？ 输出的是 Order 里面包含的客户信息
	
		// 设置 订单时间
		order.setOrderTime(new Date());
		// 设置定单编号
		order.setOrderNum(UUID.randomUUID().toString());
		// 设置订单状态 Wie带去取件
		order.setStatus("1");
		// 设置 寄件人 省市区
		Area area = order.getSendArea();
		Area persistArea = areaRepository.findByProvinceAndCityAndDistrict(area.getProvince(), area.getCity(),
				area.getDistrict());
		// 设置 收件人 省市区
		Area recArea = order.getSendArea();
		Area persistRecArea = areaRepository.findByProvinceAndCityAndDistrict(recArea.getProvince(), recArea.getCity(),
				recArea.getDistrict());
		order.setSendArea(persistRecArea);
		order.setRecArea(persistRecArea);

		// 自动分单逻辑 基于 CRM地址库 完全匹配 获取定区 匹配快递员
		// bos_management 去访问 crm_management
		String fixedAreaId = WebClient
				.create(Constants.CRM_Management_url
						+ "/services/customerService/customer/findFixedAreaIdByAddress?address="
						+ order.getSendAddress()) // get 及其里面的String.class
													// 是什么意思？？？
				.accept(MediaType.APPLICATION_JSON).get(String.class);

		// 对上面的结果进行条件判断
		if (fixedAreaId != null) { // 调用dao 层的方法 对结果进行操作？？？ findOne --的意思？？
			FixedArea fixedArea = fixedarearepository.findOne(fixedAreaId);
			Courier courier = fixedArea.getCouriers().iterator().next(); // 这又是啥意思？？？

			// 这是在判断什么？？
			if (courier != null) {
				// 自动分单成功
				System.out.println("自动分单成功.....");
				// 关联款地缘 保存订单
				saveOrder(order, courier);

				// 基于订单 生成工单 发送短信
				generateWorkBill(order);

				return;
			}

		}

		// 自动分单 逻辑 通过省市区 查询分区关键字 匹配地址 基于分区实现自动分单

		// for 里面都是什么？？ 包含什么？？？
		for (SubArea subArea : persistArea.getSubareas()) {
			// 当前客户下单地址 是否包含分区关键字啊啊
			if (order.getSendAddress().contains(subArea.getKeyWords())) {
				// 找大分区 找到定区 找到快递员
				Courier courier = subArea.getFixedArea().getCouriers().iterator().next(); // 者端语句
																							// 的到多的是什么？？

				// if 判断的是什么？？
				if (courier != null) {
					// 自动分单成功
					System.out.println("自动分单成功..");
					// 关联款地缘 保存订单
					saveOrder(order, courier);
					// 基于订单 生成工单 发送短信
					generateWorkBill(order);

					// 生成工单 发送短信
					return;
				}

			}
		}

		// 使用辅助关键字进行查找
		for (SubArea subArea : persistArea.getSubareas()) {
			// 当前客户下单地址 是否包含分区辅助关键字
			if (order.getSendAddress().contains(subArea.getAssistKeyWords())) {
				// 找大分区 找到定区 找到快递员
				Courier courier = subArea.getFixedArea().getCouriers().iterator().next(); // 者端语句
																							// 的到多的是什么？？

				// if 判断的是什么？？
				if (courier != null) {
					// 自动分单成功
					System.out.println("自动分单成功..");
					// 关联款地缘 保存订单
					saveOrder(order, courier);
					// 基于订单 生成工单 发送短信
					generateWorkBill(order);
					// 生成工单 发送短信
					return;
				}

			}
		}
		// 进入人工分单
		order.setOrderType("2");
		orderRepository.save(order);
	}

	// 生成工单 发送短信
	private void generateWorkBill(final Order order) {
		// 生成工单
		WorkBill workBill = new WorkBill();
		workBill.setType("新");
		workBill.setPickstate("新单");
		workBill.setBuildtime(new Date());
		workBill.setRemark(order.getRemark());
		final String smsNumber = RandomStringUtils.randomNumeric(4); // 生成短信验证码
		workBill.setSmsNumber(smsNumber);
		workBill.setOrder(order);
		workBill.setCourier(order.getCourier());
		workBillRepository.save(workBill);

		// 发短信
		// 调用 jmstemplate 发送一条验证码短信
		jmsTemplate.send("bos_usear", new MessageCreator() {
			@Override
			public Message createMessage(Session session) throws JMSException {
				MapMessage mapmessage = session.createMapMessage();
				mapmessage.setString("telephone", order.getCourier().getTelephone()); // 向快递员发短信
				mapmessage.setString("mrg",
						"短信序号：" + order.getSendAddress() + ", 取件地址:" + order.getSendAddress() + ", 联系人："
								+ order.getSendName() + ",手机号：" + order.getSendMobile() + ",快递员稍话："
								+ order.getSendMobileMsg());

				return mapmessage;
			}
		});

		// 修改工作状态
		workBill.setPickstate("已通知");

	}

	private void saveOrder(Order order, Courier courier) {
		// 将款地缘关联上
		order.setCourier(courier);

		// 设置自动分单
		order.setOrderType("1");
		// 保存订单
		orderRepository.save(order);
	}

	//通过订单号 将客户数据信息 回显到运单页面
	@Override
	public Order findByOrderNum(String orderNum) {
		return orderRepository.findByOrderNum(orderNum);
	}

}
